/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.pokemon.web;

import com.pokemon.dto.TrainerDTO;
import com.pokemon.entities.Month;
import com.pokemon.services.TrainerService;
import java.sql.Date;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;
import net.sourceforge.stripes.action.Before;
import net.sourceforge.stripes.action.DefaultHandler;
import net.sourceforge.stripes.action.ForwardResolution;
import net.sourceforge.stripes.action.RedirectResolution;
import net.sourceforge.stripes.action.Resolution;
import net.sourceforge.stripes.action.UrlBinding;
import net.sourceforge.stripes.controller.LifecycleStage;
import net.sourceforge.stripes.integration.spring.SpringBean;
import net.sourceforge.stripes.validation.LocalizableError;
import net.sourceforge.stripes.validation.Validate;
import net.sourceforge.stripes.validation.ValidateNestedProperties;
import net.sourceforge.stripes.validation.ValidationErrors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
@UrlBinding("/trainers/{$event}")
public class TrainerActionBean extends CustomActionBean {
    
 
    final static Logger log = LoggerFactory.getLogger(TrainerActionBean.class);
 
    @SpringBean
    protected TrainerService trainerManager;
 
    @DefaultHandler
    public Resolution all() {
        log.debug("all()");
        return new ForwardResolution("/trainer/trainer.jsp");
    }
 
    public List<TrainerDTO> getTrainers() {
        return trainerManager.getAllTrainers();
    }
    public String day;
    public String month;
    public String year;
    
    @ValidateNestedProperties(value = {
            @Validate(on = {"add", "save"}, field = "firstName", required = true),
            @Validate(on = {"add", "save"}, field = "lastName", required = true)
    })
    private TrainerDTO trainer;
    
    public List<Month> getAllMonths() {
        return Arrays.asList(Month.values());
    }
    
    public List<Integer> getAllDays() {
        List<Integer> result = new ArrayList<>();
        for (int i = 1; i <= 31; i++) {
            result.add(i);
        }
        return result;
    }
    
    public List<Integer> getAllYears() {
        List<Integer> result = new ArrayList<>();
        for (int i = Calendar.getInstance().get(Calendar.YEAR); i >= 1900 ; i--) {
            result.add(i);
        }
        return result;
    }
    
    public Resolution add() {
        log.debug("add() trainer={}", trainer);
        
        ValidationErrors errors = new ValidationErrors();
        
        Date date = this.validateDate(errors, day, month, year);
        
        if (!errors.isEmpty()){
            getContext().setValidationErrors(errors);
            return getContext().getSourcePageResolution();   
        }
        
        trainer.setBirthDate(date);
     
        trainerManager.addTrainer(trainer);
        return new RedirectResolution(this.getClass(), "all");
    }
    
    public Date validateDate(ValidationErrors errors, String dayInput, String monthInput, String yearInput) {
        int day = 1;
        int month = 1;
        int year = 1900;
        
        try {
            day = Integer.parseInt(dayInput);
        }
        catch (NumberFormatException e) {
            errors.addGlobalError( new LocalizableError("BadDayInputFormat") );
        }
        try {
            if (monthInput == null) {
                throw new NumberFormatException();
            }
            month = getAllMonths().indexOf(Month.valueOf(monthInput));
        }
        catch (NumberFormatException e) {
            errors.addGlobalError( new LocalizableError("BadMonthInputFormat") );
        }
        try{
            year = Integer.parseInt(yearInput);
        }
        catch (NumberFormatException e) {
            errors.addGlobalError( new LocalizableError("BadYearInputFormat") );
        }
        
        if (!errors.isEmpty()) {
            return null;
        }
        
        if((day > 30) && ((month == Month.APRIL.ordinal()) || (month == Month.JUNE.ordinal()) || (month == Month.SEPTEMBER.ordinal()) || (month == Month.NOVEMBER.ordinal()))) {
            errors.addGlobalError( new LocalizableError("UnrecongnizedDateInputFormat") );
        } else if((day > 29) && (month == Month.FEBRUARY.ordinal())) {
            errors.addGlobalError( new LocalizableError("UnrecongnizedDateInputFormat") );
        } else if((day == 29) && (month == Month.FEBRUARY.ordinal()) && ((year % 4 != 0) || (year % 100 == 0)) && (year % 400 != 0)) {  //can be also checked by ...&& !gregCal.isLeapYear(year);
            errors.addGlobalError( new LocalizableError("UnrecongnizedDateInputFormat") );
        }
        
        return new Date(new GregorianCalendar(year, month, day).getTimeInMillis());
    }
    
    public TrainerDTO getTrainer() {
        return trainer;
    }
 
    public String getDay(){
        return day;
    }
    public void setDay(String day){
        this.day=day;
    }

    public String getMonth() {
        return month;
    }

    public void setMonth(String month) {
        this.month = month;
    }

    public String getYear() {
        return year;
    }

    public void setYear(String year) {
        this.year = year;
    }
    
    public void setTrainer(TrainerDTO trainer) {
        this.trainer = trainer;
    }
    
    public Resolution delete() {
        log.debug("delete({})", trainer.getId());
        trainerManager.removeTrainer(trainer);
        return new RedirectResolution(this.getClass(), "all");
    }
    
    @Before(stages = LifecycleStage.BindingAndValidation, on = {"edit", "save"})
    public void loadTrainerFromDatabase() {
        String ids = getContext().getRequest().getParameter("trainer.id");
        if (ids == null) return;
        trainer = trainerManager.getTrainer(Long.parseLong(ids));
    }
 
    public Resolution edit() {
        log.debug("edit() trainer={}", trainer);
        
        Calendar pom = GregorianCalendar.getInstance();
        pom.setTime(trainer.getBirthDate());
     
        month = getAllMonths().get(pom.get(Calendar.MONTH)).toString();
        day = String.valueOf(pom.get(Calendar.DAY_OF_MONTH));
        year = String.valueOf(pom.get(Calendar.YEAR));
        
        return new ForwardResolution("/trainer/edit.jsp");
    }
 
    public Resolution save() {
        log.debug("save() trainer={}", trainer);
        
        ValidationErrors errors = new ValidationErrors();
        
        Date date = this.validateDate(errors, day, month, year);
        
        if (!errors.isEmpty()){
            getContext().setValidationErrors(errors);
            return getContext().getSourcePageResolution();   
        }
        
        trainer.setBirthDate(date);
        
        trainerManager.updateTrainer(trainer); 
        
        return new RedirectResolution(this.getClass(), "all");
    }
    
    public Resolution cancel() {
        return new RedirectResolution(this.getClass(), "all");
    }
}